Iterator pattern
假设有两个餐厅,它们各自的菜单组织形式不同。
1 | public class MenuItem { |
1 | public class PanackeHouseMenue { |
当遍历菜单时,我们需要提供两个方法遍历两种菜单,使系统变得复杂化。如果需要增加一种新的菜单,需要修改前面的很多代码,造成难以维护。
定义迭代器模式
这里我们可以把遍历封装起来,让每个类提供相同的方法遍历它自己的元素。外部客户只管调用这些方法来遍历,而不必直到内部是如何实现的。且由于所有类都提供同样的遍历方法,降低的复杂性,使得系统容易扩展和修改。
迭代其模式提供一种同一的方法顺序访问一个聚合对象中的各个元素,而由不暴露其内部的表示。把遍历的任务交给迭代器,而不是聚合对象上,这样简化了聚合对象的接口和实现,也满足了单一责任原则:一个类应该只负责一个职责,并只有一个引起变化的原因。
1 | public interface Iterator { |
1 | public class DinerMenuIterator implements Iterator { |
1 | public class DinerMenu implements Menu { |
1 | public class Waitress { |
通过迭代器,我们可以很容易的新增菜单:
1 | public class CafeMenu implements Menu { |
1 | public class Waitress { |
目前在菜单增加时,遍历菜单的方法不需要再修改。但是我们需要单独管理这些菜单,而不是能够讲它们也聚合在一起作为一个单独的聚合对象管理,通过使用基类List可以部分改进该,但是我们仍然无法在菜单里增加子菜单,也就是层级模式。
组合模式
这时我们可以使用组合模式解决这个难题:
定义组合模式
组合模式允许我们将组合对象组合成树形结构来表现”整体/部分”层次结构。组合能够让客户以一致的方式处理个别对象以及对象组合。
这里我们使用组合设计菜单:
1 | public abstract class MenuComponent { |
1 | public class MenuItem extends MenuComponent { |
1 | public class Menu extends MenuComponent { |
1 | public class Waitress { |
组合模式和组合迭代器
递归实现:
1 | public class MenuItem extends MenuComponent { |
1 | public class Menu extends MenuComponent { |
1 | public class NullIterator implements Iterator { |
1 | public class CompositeIterator implements Iterator { |